home *** CD-ROM | disk | FTP | other *** search
/ Pascal Super Library / Pascal Super Library (CW International)(1997).bin / LIBRARY / WCTUNITS / XGRAPH.PAS < prev   
Pascal/Delphi Source File  |  1991-07-30  |  9KB  |  297 lines

  1. unit xgraph;
  2.  
  3. { Written by William C. Thompson (wct@po.cwru.edu) - 1991 }
  4.  
  5. { This unit was written for programs with heavy graphics usage.
  6.   There are a number of procedures to make graphics more bearable.
  7.   There are some procedures that do different drawings.
  8.   There are some procedures that can save/recall a screen image. }
  9.  
  10. { Designer's Notes:
  11.  
  12.   1. I have left some of the error checking, such as checking if
  13.      a file exists or not, out of the procedures.  That is the
  14.      responsibility of the programmer. }
  15.  
  16. interface
  17.  
  18. uses graph,math;
  19.  
  20. type
  21.   imagebuffer=array[0..65534] of byte;
  22.   image=record
  23.     p: ^imagebuffer;   { buffer for image }
  24.     size: word;   { size of image }
  25.     end;
  26.   { Instead of making p a generic pointer, I decided to make it
  27.     point to an array, so the contents of the array could be examined
  28.     more easily if the programmer so desired. }
  29.  
  30. var
  31.   europeanfont,complexfont,triplexscriptfont,scriptfont,simplefont:integer;
  32.  
  33. procedure setfillcolor(col:word);
  34. procedure setfillpatt(pat: word);
  35. procedure settextfont(font:word);
  36. procedure settextsize(size:word);
  37. procedure settextdir(dir:word);
  38. procedure settextall(font,dir,size,hor,ver:word);
  39. procedure xouttextxy(x1,y1:word; spacing:byte; s:string);
  40. procedure ngon(cx,cy,sides: word; r,ang: real);
  41. procedure fline(x1,y1,x2,y2:word; warp,pixres:real);
  42. procedure fbranch(fn:string ; warp,pixres:real);
  43. procedure frip(fn: string; warp,pixres: real);
  44. procedure writeimage(fn:string; var im:image);
  45. procedure readimage(fn:string; var im:image);
  46. procedure grabimage(x1,y1,x2,y2:word; var im:image);
  47. procedure showimage(x1,y1: word; var im:image; bitblt:word);
  48. procedure killimage(var im:image);
  49.  
  50. implementation
  51.  
  52. procedure setfillcolor(col:word);
  53. var
  54.   s: fillsettingstype;
  55. begin
  56.   getfillsettings(s);
  57.   setfillstyle(s.pattern,col)
  58. end;
  59.  
  60. procedure setfillpatt(pat: word);
  61. var
  62.   s: fillsettingstype;
  63. begin
  64.   getfillsettings(s);
  65.   setfillstyle(pat,s.color)
  66. end;
  67.  
  68. procedure settextfont(font:word);
  69. var
  70.   s: textsettingstype;
  71. begin
  72.   gettextsettings(s);
  73.   settextstyle(font, s.direction, s.charsize)
  74. end;
  75.  
  76. procedure settextsize(size:word);
  77. var
  78.   s: textsettingstype;
  79. begin
  80.   gettextsettings(s);
  81.   settextstyle(s.font, s.direction, size)
  82. end;
  83.  
  84. procedure settextdir(dir:word);
  85. var
  86.   s: textsettingstype;
  87. begin
  88.   gettextsettings(s);
  89.   settextstyle(s.font, dir, s.charsize)
  90. end;
  91.  
  92. procedure settextall(font,dir,size,hor,ver:word);
  93. { This is an EXTREMELY useful procedure to set all attributes of
  94.   graphics text settings. }
  95. begin
  96.   settextstyle(font,dir,size);
  97.   settextjustify(hor,ver)
  98. end;
  99.  
  100. procedure xouttextxy(x1,y1:word; spacing:byte; s:string);
  101. { Writing text in graphics mode can be very tedious.  If you want
  102.   to write line after line after line, you have to type OutTextXY
  103.   about a million times and make quite a few mistakes doing it.
  104.   This is usually a big headache for me and makes me not want to
  105.   work on whatever I'm doing because it's so tedious.  And thus
  106.   a procedure was born.  What this procedure does is start writing
  107.   at (x1,y1) when it finds #13 in the string, it skips down Spacing
  108.   pixels and writes until the next #13, and so on.  This lets you
  109.   change the spacing and move the text around more easily.  You are
  110.   still limited to 255 characters, but it's still worth it. }
  111. var
  112.   j: word;
  113.   p: byte;
  114. begin
  115.   j:=y1;
  116.   while s<>'' do begin
  117.     { find #13 in string }
  118.     p:=pos(#13,s);
  119.     if p>0 then begin
  120.       outtextxy(x1,j,copy(s,1,p-1));
  121.       delete(s,1,p);
  122.       j:=j+spacing
  123.       end
  124.     else begin
  125.       outtextxy(x1,j,s);
  126.       s:=''
  127.       end
  128.     end
  129. end;
  130.  
  131. procedure ngon(cx,cy,sides: word; r,ang: real);
  132. { This procedure draws an n-sided polygon.  (Cx,Cy) is the center.
  133.   Sides is obviously the number of sides.  R is the distance from
  134.   the center to one of the elbows, and Ang is the angle of rotation.
  135.   Ang must be given in radians. }
  136. var
  137.   i: word;
  138. begin
  139.   for i:=0 to sides-1 do
  140.     line(round(cx+r*cos(i/sides*2*pi+ang-pi/2)),
  141.          round(cy+r*sin(i/sides*2*pi+ang-pi/2)),
  142.          round(cx+r*cos((i+1)/sides*2*pi+ang-pi/2)),
  143.          round(cy+r*sin((i+1)/sides*2*pi+ang-pi/2)));
  144. end;
  145.  
  146. procedure fline(x1,y1,x2,y2:word; warp,pixres:real);
  147. { Generates a fractal line from (x1,y1) bent by Warp % such that no
  148.   two points are more than PixRes pixels apart.  A higher Warp means
  149.   the line can deviate more.  Caution: a Warp above 1.0 is not good }
  150. var
  151.   d,ang:real;
  152.   x3,y3:word;        { point of bend }
  153. begin
  154.   d:=distance(x1,y1,x2,y2);
  155.   if d<=pixres then line(x1,y1,x2,y2)
  156.   else begin
  157.     ang:=random(65535)*9.5875262E-5;       { generate [0,2 pi) }
  158.     x3:=round((x1+x2)/2+d/2*warp*sin(ang));
  159.     y3:=round((y1+y2)/2+d/2*warp*cos(ang));
  160.     fline(x1,y1,x3,y3,warp,pixres);
  161.     fline(x3,y3,x2,y2,warp,pixres)
  162.     end
  163. end;
  164.  
  165. procedure fbranch(fn:string; warp,pixres:real);
  166. { reads a fractal branch file from disk and draws it with
  167.   parameters warp and pixres, as described in fline.  There
  168.   is a maximum of MaxNodes nodes, but only as much space as
  169.   needed is allocated.  Define a branch as follows:
  170.  
  171.   number of nodes                         e.g.  5
  172.   list of each node's coordinates               100 100
  173.                                                 ...
  174.   list of connections from node to node         1 2
  175.                                                 ... }
  176. const
  177.   maxnodes=1000;
  178. type
  179.   nodelist=array[1..2*maxnodes] of word;
  180. var
  181.   f: text;
  182.   i: word;
  183.   a,b: word;             { node numbers }
  184.   pts: word;             { number of nodes }
  185.   nl: ^nodelist;         { pointer to list of nodes }
  186. begin
  187.   assign(f,fn);
  188.   reset(f);
  189.   { read in points }
  190.   readln(f,pts);
  191.   if pts<=maxnodes then getmem(nl,pts*4) else getmem(nl,maxnodes*4);
  192.   for i:=1 to pts do
  193.     if i<=maxnodes then readln(f,nl^[i*2-1],nl^[i*2]) else readln(f);
  194.   while not eof(f) do begin
  195.     readln(f,a,b);
  196.     if [a,b]*[1..pts]=[a,b] then
  197.       fline(nl^[a*2-1],nl^[a*2],nl^[b*2-1],nl^[b*2],warp,pixres)
  198.     end;
  199.   close(f);
  200. end;
  201.  
  202. procedure frip(fn:string; warp,pixres:real);
  203. { Reads and draws a fractal rip (looks like a river)
  204.   A rip file is defined as follows:
  205.  
  206.   List of coordinates to connect    e.g.    100 100
  207.                                             150 120
  208.                                             160 180
  209.                                             ...
  210.  
  211.   This can be used to draw lakes, borders, etc.
  212.   There is no limit on the number of nodes. }
  213. var
  214.   x1,y1,x2,y2: word;
  215.   f: text;
  216. begin
  217.   assign(f,fn);
  218.   reset(f);
  219.   { read first point }
  220.   readln(f,x1,y1);
  221.   while not eof(f) do begin
  222.     readln(f,x2,y2);
  223.     fline(x1,y1,x2,y2,warp,pixres);
  224.     x1:=x2;
  225.     y1:=y2
  226.     end;
  227.   close(f)
  228. end;
  229.  
  230. procedure writeimage(fn:string; var im:image);
  231. { This procedure writes an image to the specified file. }
  232. var
  233.   f: file;
  234.   p: pointer;
  235.   n: word;
  236. begin
  237.   assign(f,fn);
  238.   rewrite(f,1);                    { objects are 1 byte large }
  239.   blockwrite(f,im.p^,im.size,n);   { write image to disk }
  240.   close(f);
  241. end;
  242.  
  243. procedure readimage(fn:string; var im:image);
  244. { There is no error checking as to how much memory is available.  The
  245.   size of an image is approximately the number of pixels divided by
  246.   two (VGA mode).  A good use of this procedure is to write a program that
  247.   draws a fairly complex image to be used in another program.  Then, use
  248.   GrabImage to capture the smallest area containing the image you want
  249.   and WriteImage to save it to disk.  Then use ReadImage and ShowImage to
  250.   draw the image in another program.  That way the image doesn't have to be
  251.   drawn at run-time. }
  252. var
  253.   f: file;
  254.   n: word;
  255. begin
  256.   assign(f,fn);
  257.   reset(f,1);
  258.   im.size:=filesize(f);           { assumes entire file is image }
  259.   getmem(im.p,im.size);           { allocate space }
  260.   blockread(f,im.p^,im.size,n);   { read in image }
  261.   close(f);
  262. end;
  263.  
  264. procedure grabimage(x1,y1,x2,y2:word; var im:image);
  265. { This procedure captures the specified image into a buffer.  It also
  266.   allocates enough memory, which can be released with KillImage.  This
  267.   is very similar to GetImage, but I have hidden away the details and
  268.   memory (de)allocation to make the procedures more complementary. }
  269. begin
  270.   im.size:=imagesize(x1,y1,x2,y2);
  271.   getmem(im.p,im.size);
  272.   getimage(x1,y1,x2,y2,im.p^)
  273. end;
  274.  
  275. procedure showimage(x1,y1:word; var im:image; bitblt:word);
  276. { The only difference between this and PutImage is the programmer
  277.   specifies an image instead of a buffer.  This helps to preserve
  278.   consistency. }
  279. begin
  280.   putimage(x1,y1,im.p^,bitblt)
  281. end;
  282.  
  283. procedure killimage(var im:image);
  284. { This procedure deallocates any memory used to store an image. }
  285. begin
  286.   freemem(im.p,im.size);
  287.   im.size:=0;
  288. end;
  289.  
  290. begin
  291.   europeanfont:=installuserfont('euro');
  292.   complexfont:=installuserfont('lcom');
  293.   triplexscriptfont:=installuserfont('tscr');
  294.   scriptfont:=installuserfont('scri');
  295.   simplefont:=installuserfont('simp');
  296. end.
  297.